1//////////////////////////////////////////////////////////////////////
  2// LibFile: wiring.scad
  3//   Rendering for routed wire bundles
  4// Includes:
  5//   include <BOSL2/std.scad>
  6//   include <BOSL2/wiring.scad>
  7// FileGroup: Parts
  8// FileSummary: Routed bundles of wires.
  9//////////////////////////////////////////////////////////////////////
 10
 11include <rounding.scad>
 12
 13
 14/// Function: _hex_offset_ring()
 15/// Usage:
 16///   _hex_offset_ring(d, lev)
 17/// Description:
 18///   Returns a hexagonal ring of points, with a spacing of `d`.
 19///   If `lev=0`, returns a single point at `[0,0]`.  All greater
 20///   levels return `6 * lev` points.
 21/// Arguments:
 22///   d = Base unit diameter to build rings upon.
 23///   lev = How many rings to produce.
 24/// Example:
 25///   _hex_offset_ring(d=1, lev=3); // Returns a hex ring of 18 points.
 26function _hex_offset_ring(d, lev=0) =
 27    (lev == 0)? [[0,0]] :
 28    reverse(subdivide_path(hexagon(r=lev*d), refine=lev));
 29
 30
 31/// Function: _hex_offsets()
 32/// Usage:
 33///   _hex_offsets(n, d)
 34/// Description:
 35///   Returns the centerpoints for the optimal hexagonal packing
 36///   of at least `n` circular items, of diameter `d`.  Will return
 37///   enough points to fill out the last ring, even if that is more
 38///   than `n` points.
 39/// Arguments:
 40///   n = Number of items to bundle.
 41///   d = How far to space each point away from others.
 42function _hex_offsets(n, d, lev=0, arr=[]) =
 43    (len(arr) >= n)? arr :
 44        _hex_offsets(
 45            n=n,
 46            d=d,
 47            lev=lev+1,
 48            arr=concat(arr, _hex_offset_ring(d, lev=lev))
 49        );
 50
 51
 52
 53// Section: Modules
 54
 55
 56// Module: wire_bundle()
 57// Synopsis: Creates a wire bundle for a given number of wires.
 58// SynTags: Geom
 59// Topics: Wiring
 60// See Also: path_sweep(), path_sweep2d()
 61// Usage:
 62//   wire_bundle(path, wires, [wirediam], [rounding], [wirenum=], [corner_steps=]);
 63// Description:
 64//   Returns a 3D object representing a bundle of wires that follow a given path,
 65//   with the corners rounded to a given radius.  There are 17 base wire colors.
 66//   If you have more than 17 wires, colors will get re-used.
 67// Arguments:
 68//   path = The 3D path that the wire bundle should follow.
 69//   wires = The number of wires in the wire bundle.
 70//   wirediam = The diameter of each wire in the bundle.
 71//   rounding = The radius that the path corners will be rounded to.
 72//   ---
 73//   wirenum = The first wire's offset into the color table.
 74//   corner_steps = The corner roundings in the path will be converted into this number of segments.
 75// Example:
 76//   wire_bundle([[50,0,-50], [50,50,-50], [0,50,-50], [0,0,-50], [0,0,0]], rounding=10, wires=13);
 77module wire_bundle(path, wires, wirediam=2, rounding=10, wirenum=0, corner_steps=15) {
 78    no_children($children);
 79    colors = [
 80        [0.2, 0.2, 0.2], [1.0, 0.2, 0.2], [0.0, 0.8, 0.0], [1.0, 1.0, 0.2],
 81        [0.3, 0.3, 1.0], [1.0, 1.0, 1.0], [0.7, 0.5, 0.0], [0.5, 0.5, 0.5],
 82        [0.2, 0.9, 0.9], [0.8, 0.0, 0.8], [0.0, 0.6, 0.6], [1.0, 0.7, 0.7],
 83        [1.0, 0.5, 1.0], [0.5, 0.6, 0.0], [1.0, 0.7, 0.0], [0.7, 1.0, 0.5],
 84        [0.6, 0.6, 1.0],
 85    ];
 86    sides = max(segs(wirediam/2), 8);
 87    offsets = _hex_offsets(wires, wirediam);
 88    rounded_path = round_corners(path, radius=rounding, $fn=(corner_steps+1)*4, closed=false);
 89    attachable(){
 90      for (i = [0:1:wires-1]) {
 91          extpath = move(offsets[i], p=circle(d=wirediam, $fn=sides));
 92          color(colors[(i+wirenum)%len(colors)]) {
 93              path_sweep(extpath, rounded_path);
 94          }
 95      }
 96      union();
 97    }
 98}
 99
100
101
102// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap